package com.hhkj.admin.question.domain;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.hhkj.admin.question.common.cont.QuestionTypeEnum;
import com.hhkj.admin.question.common.mybatis.handler.OptionListHandler;
import com.hhkj.admin.question.model.extend.Option;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BizBaseEntity;
import com.ruoyi.common.valid.VEdit;
import com.ruoyi.common.valid.VPage;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 题目信息对象 t_question
 *
 * @author ruoyi
 * @since 2023-05-16
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName(value = "t_question", autoResultMap = true)
public class Question extends BizBaseEntity
{
    private static final long serialVersionUID = 1L;

    /** 是否案例题 1-是 0-否 */
    @Excel(name = "是否案例题 1-是 0-否")
    @TableField(updateStrategy = FieldStrategy.NEVER)
    private Integer caseFlag;

    /** 题目类型 single 单选题、 multiple 多选题、 judge 判断题、case 案例题 */
    @Excel(name = "题目组类型 编码 single 单选题、 multiple 多选题、 judge 判断题 、 case 案例题")
    @TableField(updateStrategy = FieldStrategy.NEVER)
    private String typeCode;

    /** 题目类型名称 */
    @TableField(exist = false)
    private String typeName;

    /** 上级题目id 默认 0 */
    private Long parentId;

    /** 题目内容 */
    @Excel(name = "题目内容")
    @NotBlank(message = "题目内容不能为空", groups = {VEdit.class})
    private String content;

    /** 选项内容[{"option":"A","content":"选项A"}] */
    @Excel(name = "选项内容")
    @TableField(typeHandler = OptionListHandler.class)
    private List<Option> optionList;

    /** 题目答案 */
    @Excel(name = "题目答案")
    private String answer;

    /** 题目分析 */
    @Excel(name = "题目分析")
    private String analysisContent;

    /** 题目导入时候的排序序号 */
    @TableField(updateStrategy = FieldStrategy.NEVER)
    private Integer importOrderNum;

    /** 题库id */
    @NotNull(message = "题库信息不能为空", groups = {VPage.class})
    @TableField(exist = false)
    private Long bankId;

    /** 题库id列表 */
    @TableField(exist = false)
    private List<Long> bankIdList;

    /** 学生答案 */
    @TableField(exist = false)
    private String studentAnswer;

    /** 学生答案 */
    @TableField(exist = false)
    private String correctResCode;

    /** 排序序号 */
    @TableField(exist = false)
    private Integer orderNum;

    /** 题目分数信息 */
    @TableField(exist = false)
    private BigDecimal mark;

    /** 学员得分信息 */
    @JsonIgnore
    @TableField(exist = false)
    private BigDecimal studentMark;

    /** 漏选得一半标签 */
    @TableField(exist = false)
    private boolean incompleteHalfMarkFlag;

    /** 实际排序序号列表 */
    @TableField(exist = false)
    private List<String> actualOptionOrderList;

    /** 实际答案 */
    @TableField(exist = false)
    private String actualAnswer;

    public String getTypeName()
    {
        return QuestionTypeEnum.getNameByCode(this.typeCode);
    }

    @Override
    @NotNull(message = "唯一主键不能为空", groups = {VEdit.class})
    public Long getId()
    {
        return super.getId();
    }

    @JsonIgnore
    public Integer getImportOrderNum()
    {
        return importOrderNum;
    }

    @JsonIgnore
    public Integer getOrderNum()
    {
        return orderNum;
    }

    public void shuffleOptionList()
    {
        // 原选项列表信息
        List<String> origOptionList = this.optionList.stream().map(Option::getOption).collect(Collectors.toList());
        // 实际的选项标签 ABCD 排序列表
        Collections.shuffle(this.optionList);
        this.actualOptionOrderList = this.optionList.stream().map(Option::getOption).collect(Collectors.toList());
        // 选项信息
        Option option;
        // 选项标签
        String optionLab;
        String finalAnswer = this.answer;
        this.actualAnswer = this.answer;
        for (int i = 0; i < this.optionList.size(); i++) {
            // 获取对应下下标 选项
            option = this.optionList.get(i);
            // 获取对应下标的选项标签
            optionLab = origOptionList.get(i);
            // 如果答案不为空 并且 当前的答案
            if (StrUtil.isNotBlank(this.answer)
                    && this.answer.equals(option.getOption())) {
                finalAnswer = optionLab;
            }
            option.setOption(optionLab);
        }
        this.answer = finalAnswer;
    }

    public void reductionShuffleOptionList(List<String> actualOptionOrderList)
    {
        Map<String, Option> optionMapByOption = this.optionList.stream()
                .collect(Collectors.groupingBy(Option::getOption,
                        Collectors.collectingAndThen(Collectors.toList(), CollectionUtil::getFirst)));
        List<String> origOptionList = this.optionList.stream().map(Option::getOption).collect(Collectors.toList());
        List<Option> reductionOptionList = new ArrayList<>();

        if (origOptionList.size() != actualOptionOrderList.size()) {
            return;
        }
        String origOption;
        Option shuffleOption;
        String finalAnswer = this.answer;
        for (int i = 0; i < actualOptionOrderList.size(); i++) {
            origOption = origOptionList.get(i);
            shuffleOption = optionMapByOption.get(actualOptionOrderList.get(i));
            if (StrUtil.isNotBlank(this.answer)
                    && this.answer.equals(shuffleOption.getOption())) {
                finalAnswer = origOption;
            }
            // 修改答案信息
            shuffleOption.setOption(origOption);
            reductionOptionList.add(shuffleOption);
        }
        this.answer = finalAnswer;
        this.optionList = reductionOptionList;
    }
}
